package dk.eclipse.android.badassapp.widget;

import java.util.List;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;
import dk.eclipse.android.badassapp.R;
import dk.eclipse.android.badassapp.helper.SoundHelper;
import dk.eclipse.android.badassapp.preferences.PreferenceHelper;
import dk.eclipse.android.badassapp.weapon.Weapon;
import dk.eclipse.android.badassapp.weapon.WeaponActivity;
import dk.eclipse.android.badassapp.weapon.WeaponHelper;

/**
 * @author Ronni Kahalani (eclipse.dk)
 * 
 */
public class WeaponWidget extends AppWidgetProvider {
	/**
	 * Tag used for logging information.
	 */
	private static final String LOG_TAG = WeaponWidget.class.getSimpleName();

	public static final String ACTION_WEAPON_CHANGED = "dk.eclipse.android.badassapp.widget.ACTION_WEAPON_CHANGED";
	public static final String ACTION_PLAY_SOUND = "dk.eclipse.android.badassapp.widget.ACTION_PLAY_SOUND";
	public static final String ACTION_PREVIOUS_WEAPON = "dk.eclipse.android.badassapp.widget.ACTION_NEXT_WEAPON";
	public static final String ACTION_NEXT_WEAPON = "dk.eclipse.android.badassapp.widget.ACTION_PREVIOUS_WEAPON";

	/**
	 * 
	 */
	private Context currentContext;
	private int currentWeaponIndex = -1;
	private Weapon selectedWeapon;
	private RemoteViews appWidgetViews;
	private AppWidgetManager appWidgetManager;

	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds) {
		currentContext = context;
		this.appWidgetManager = appWidgetManager;
		updateUI(context);
		super.onUpdate(context, appWidgetManager, appWidgetIds);
	}

	/**
	 * Updates the user interface.
	 * 
	 * @param context
	 */
	private void updateUI(Context context) {
		Log.i(LOG_TAG, "Updating widget UI.");
		
		// Update the user interface.
		appWidgetViews = new RemoteViews(context.getPackageName(),
				R.layout.weapon_widget);

		// An intent to open the weapon gallery.
		PendingIntent showWeaponsIntent = PendingIntent.getActivity(context, 0,
				new Intent(context, WeaponActivity.class), 0);

		// An intent to play the selected weapon sound.
		PendingIntent playSoundIntent = PendingIntent.getBroadcast(context, 0,
				new Intent(ACTION_PLAY_SOUND), 0);

		// An intent to select the next weapon.
		PendingIntent nextWeaponIntent = PendingIntent.getBroadcast(context, 0,
				new Intent(ACTION_NEXT_WEAPON), 0);

		// An intent to select the previous weapon.
		PendingIntent previousWeaponIntent = PendingIntent.getBroadcast(
				context, 0, new Intent(ACTION_PREVIOUS_WEAPON), 0);

		// Add click intents for the different controls.
		appWidgetViews.setOnClickPendingIntent(R.id.selectWeaponWidgetButton,
				showWeaponsIntent);
		appWidgetViews.setOnClickPendingIntent(R.id.useWeaponWidgetButton,
				playSoundIntent);
		appWidgetViews.setOnClickPendingIntent(R.id.widgetWeaponImageButton,
				playSoundIntent);
		appWidgetViews.setOnClickPendingIntent(R.id.previousWeaponWidgetButton,
				previousWeaponIntent);
		appWidgetViews.setOnClickPendingIntent(R.id.nextWeaponWidgetButton,
				nextWeaponIntent);

		selectedWeapon = getSelectedWeapon();
		appWidgetViews.setTextViewText(R.id.widget_textview, selectedWeapon
				.getName());
		appWidgetViews.setImageViewResource(R.id.widgetWeaponImageButton,
				selectedWeapon.getImageId());

		// Tell the widget updater to use the widget views.
		appWidgetManager.updateAppWidget( new ComponentName(context,
				WeaponWidget.class), appWidgetViews);
	}

	/**
	 * Returns the currently selected weapon.
	 * 
	 * @return the selected weapon or null if not available.
	 */
	private Weapon getSelectedWeapon() {
		int index = PreferenceHelper.getPreferredWeapon(currentContext);
		if (currentWeaponIndex == index && selectedWeapon != null) {
			return selectedWeapon;
		}

		List<Weapon> weapons = WeaponHelper.getWeapons();
		currentWeaponIndex = index;
		if (isValidWeaponIndex(index)) {
			selectedWeapon = weapons.get(index);
		} else {
			selectedWeapon = null;
		}
		return selectedWeapon;
	}

	@Override
	public void onReceive(Context context, Intent intent) {

		boolean isUpdateNeeded = false;
		final String action = intent.getAction();
		currentContext = context;

		Log.i(LOG_TAG, "OnReceive: " + action);
		
		if (ACTION_WEAPON_CHANGED.equals(action)) {
			isUpdateNeeded = true;

		} else if (ACTION_PLAY_SOUND.equals(action)) {
			playWeaponSound();

		} else if (ACTION_NEXT_WEAPON.equals(action)) {
			selectNextWeapon();
			isUpdateNeeded = true;

		} else if (ACTION_PREVIOUS_WEAPON.equals(action)) {
			selectPreviousWeapon();
			isUpdateNeeded = true;
			
		} else if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {

			final int appWidgetId = intent.getExtras().getInt(
					AppWidgetManager.EXTRA_APPWIDGET_ID,
					AppWidgetManager.INVALID_APPWIDGET_ID);

			if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
				this.onDeleted(context, new int[] { appWidgetId });
			}
		} else {
			super.onReceive(context, intent);
		}

		if (isUpdateNeeded) {

			AppWidgetManager appWidgetManager = AppWidgetManager
					.getInstance(context);
			int[] appWidgetIds = appWidgetManager
					.getAppWidgetIds(new ComponentName(context,
							WeaponWidget.class));

			onUpdate(context, appWidgetManager, appWidgetIds);
		
		}
	}

	/**
	 * Handles selecting the previous weapon.
	 */
	private void selectPreviousWeapon() {
		int index = PreferenceHelper.getPreferredWeapon(currentContext);
		int maxIndex = WeaponHelper.getWeapons().size() - 1;
		if (index > 0) {
			index--;
		} else {
			index = maxIndex;
		}
		PreferenceHelper.setPreferredWeapon(currentContext, index);
	}

	/**
	 * Handles selecting the next weapon.
	 */
	private void selectNextWeapon() {
		int index = PreferenceHelper.getPreferredWeapon(currentContext);
		int maxIndex = WeaponHelper.getWeapons().size() - 1;
		if (index < maxIndex) {
			index++;
		} else {
			index = 0;
		}
		PreferenceHelper.setPreferredWeapon(currentContext, index);
	}

	/**
	 * Plays the sound for the currently selected weapon.
	 */
	private void playWeaponSound() {
		selectedWeapon = getSelectedWeapon();
		if (selectedWeapon != null) {

			SoundHelper.playSound(currentContext, selectedWeapon.getSoundId(),
					false);
		}
	}

	/**
	 * Checks to see if the index is referencing a valid weapon list entry.
	 * 
	 * @param index
	 * @return true if index is valid.
	 */
	private boolean isValidWeaponIndex(int index) {
		List<Weapon> weapons = WeaponHelper.getWeapons();
		if (index < weapons.size()) {
			return true;
		}
		return false;
	}

	@Override
	public void onDeleted(Context context, int[] appWidgetIds) {
		Toast
				.makeText(context, "Deleting weapon widget...",
						Toast.LENGTH_SHORT).show();
		super.onDeleted(context, appWidgetIds);
	}

}
